home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
wil4c10.zip
/
ASYNC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-26
|
15KB
|
475 lines
/*
** ASYNC.C
**
** AsyncExpectedRead After connecting/writing to server, we expect...
** ================== ================================================
** ASYNC_NONE == 0 No response line(s).
** ASYNC_SINGLE_LINE Single line of text from server.
** ASYNC_MULTIPLE_LINES Multiple lines of text from server, last with '.'.
** ASYNC_SINGLE_CODED Single line of text, preceeded with code.
** ASYNC_MULTIPLE_CODED Multiple lines of text, preceeded with code.
** ASYNC_PLUS_MINUS Single line of text, preceeded with + or - [POP3].
**
** WINSOCK.H defines:
**
** FD_READ = 1 ( 0x01 )
** FD_WRITE = 2 ( 0x02 )
** FD_OOB = 4 ( 0x04 )
** FD_ACCEPT = 8 ( 0x08 )
** FD_CONNECT = 16 ( 0x10 )
** FD_CLOSE = 32 ( 0x20 )
*/
#include <windows.h>
#include <winsock.h>
#include "wil.h"
#include "async.h"
#include "paint.h"
#include "str.h"
#define QUOTE 0x22
#define MAX_BUF 128
#if 1
/* no prefix */
#define SERVER_PREFIX
#define CLIENT_PREFIX
#else
#define SERVER_PREFIX DisplayString("S:");
#define CLIENT_PREFIX DisplayString("C:");
#endif
/* WM_USER messages are reserved for WIL async events */
static int TheSocket = 0; /* the socket */
static int AsyncExpectedRead = 0; /* expected read type [defined in ASYNC.H] */
static int AsyncSuccessMsg = 0; /* success message */
static int AsyncFailureMsg = 0; /* failure message */
static int AsyncReadCount = 0; /* number of lines read */
static int AsyncResponse = 0; /* numeric response code from server */
static int AsyncCmdLength = 0; /* length of AsyncCmdText[] */
static LPSTR AsyncCmdPtr = NULL; /* pointer to AsyncCmdText[] */
static char AsyncCmdText[MAX_BUF]; /* command text buffer */
static char InBuffer[MAX_BUF]; /* input buffer */
static char Temp[MAX_BUF+16]; /* temporary buffer */
static ULONG HostAddr = 0; /* host address */
static HWND hMainWnd = (HWND)0; /* main window handle */
static int EchoFlag = TRUE; /* echo flag */
static int DebugFlag = FALSE; /* debug flag */
static int MsgEnabled = 0; /* FD_* messages allowed */
/* display error text & post message */
void PostError(int Code, LPSTR Text, int UserMsg)
{MsgEnabled = 0;
wilAwaitCancel(TheSocket, hMainWnd);
wsprintf((LPSTR)Temp,"Async Error %d: ",Code);
DisplayString((LPSTR)Temp);
if(Text) DisplayString((LPSTR)Text);
if(Code<0)
{wilErrorText(Code,(LPSTR)Temp,MAX_BUF);
DisplayLine((LPSTR)Temp);
}
if(UserMsg) POST_MSG(UserMsg);
}
/* attempt connection to server */
SOCKET AsyncConnect(HWND hWnd, /* window to post messages */
LPSTR ServerType, /* server type (eg: mail.iquest.com) */
LPSTR ServerName, /* server name (eg: POP3) */
int Port, /* sever port */
int SuccessMsg, /* wParam for WM_MSG if successful */
int FailureMsg, /* wParam for WM_MSG if failure */
int ExpectRead) /* expected response type after connecting */
{int Code;
/* save parms */
hMainWnd = hWnd;
AsyncSuccessMsg = SuccessMsg;
AsyncFailureMsg = FailureMsg;
AsyncExpectedRead = ExpectRead;
AsyncResponse = 0;
wsprintf((LPSTR)Temp,"Looking for %s server %c%s%c",
(LPSTR)ServerType,QUOTE,(LPSTR)ServerName,QUOTE);
DisplayLine((LPSTR)Temp);
/* get server IP addresss */
Code = wilAskHostByName((LPSTR)ServerName);
if(Code<0)
{PostError(Code,"No such server: ",0);
return (SOCKET)0;
}
/* get host address */
HostAddr = wilGetHostAddr(0);
if(HostAddr==0)
{PostError(0, "Cannot get IP addess", 0);
return (SOCKET)0;
}
/* display server address */
wsprintf((LPSTR)Temp,"Address of server is %s\n", wilGetHostDotted(0) );
DisplayLine((LPSTR)Temp);
/* create TCP socket */
TheSocket = wilTcpSocket();
if((int)TheSocket<0)
{PostError((int)TheSocket,"Socket error: ",0);
return (SOCKET)0;
}
/* WM_USER message will be sent when connect is completed */
MsgEnabled = FD_CONNECT;
wilAwaitConnect(TheSocket,hMainWnd);
/* initiate connection to remote host */
DisplayString("Connecting to server ... ");
Code = wilConnect(TheSocket,HostAddr,Port);
if(Code<0)
{PostError(Code,"Connect: ",0);
return (SOCKET)0;
}
/* waiting for connection */
return TheSocket;
}
/* await server text */
int AsyncRead(int SuccessMsg, /* wParam for WM_MSG if successful */
int FailureMsg, /* wParam for WM_MSG if failure */
int ReadType) /* async read type */
{
if(DebugFlag)
{wsprintf((LPSTR)Temp,"AsyncRead(%d,%d)", SuccessMsg, FailureMsg);
DisplayLine((LPSTR)Temp);
}
AsyncSuccessMsg = SuccessMsg;
AsyncFailureMsg = FailureMsg;
AsyncExpectedRead = ReadType;
AsyncReadCount = 0;
AsyncResponse = 0;
MsgEnabled = FD_READ;
wilAwaitRead(TheSocket,hMainWnd);
return TRUE;
}
/* send text to server */
int AsyncWrite(LPSTR Command, /* command to send to server */
int SuccessMsg, /* wParam for WM_MSG if successful */
int FailureMsg) /* wParam for WM_MSG if failure */
{
if(Command==NULL) return FALSE;
if(DebugFlag)
{wsprintf((LPSTR)Temp,"AsyncWrite(%c%s%c,%d,%d)",
QUOTE, Command, QUOTE,
SuccessMsg, FailureMsg);
DisplayLine((LPSTR)Temp);
}
AsyncSuccessMsg = SuccessMsg;
AsyncFailureMsg = FailureMsg;
AsyncExpectedRead = ASYNC_NONE;
StringCopy((LPSTR)AsyncCmdText, (LPSTR)Command, MAX_BUF);
AsyncCmdLength = lstrlen((LPSTR)AsyncCmdText);
AsyncCmdPtr = (LPSTR) &AsyncCmdText[0];
MsgEnabled = FD_WRITE;
wilAwaitWrite(TheSocket,hMainWnd);
return TRUE;
}
/* send text to server, then await response */
int AsyncCommand(LPSTR Command, /* command to send to server */
int SuccessMsg, /* wParam for WM_MSG if successful */
int FailureMsg, /* wParam for WM_MSG if failure */
int ExpectRead) /* expected response type (if any) */
{
if(Command==NULL) return FALSE;
if(DebugFlag)
{wsprintf((LPSTR)Temp,"AsyncCommand(%c%s%c,%d,%d,%d)",
QUOTE, Command, QUOTE,
SuccessMsg, FailureMsg, ExpectRead);
DisplayLine((LPSTR)Temp);
}
AsyncSuccessMsg = SuccessMsg;
AsyncFailureMsg = FailureMsg;
AsyncExpectedRead = ExpectRead;
AsyncCmdPtr = (LPSTR) &AsyncCmdText[0];
StringCopy(AsyncCmdPtr, Command, MAX_BUF);
AsyncCmdLength = lstrlen((LPSTR)AsyncCmdText);
MsgEnabled = FD_WRITE;
wilAwaitWrite(TheSocket,hMainWnd);
return TRUE;
}
/*
** AsyncProcessMsg should be called from the WM_USER case
** event loop of the main program.
**
** It returns TRUE if the message was recognized.
*/
int AsyncProcessMsg(LONG lParam)
{int Code;
/* process WM_USER message */
switch( LOWORD(lParam) )
{
case FD_CONNECT:
/* connection to server is completed */
if(MsgEnabled!=FD_CONNECT) return TRUE;
DisplayLine("Connection complete.");
/* do we expect a response from the server ? */
if(AsyncExpectedRead)
{/* expect a response from server */
MsgEnabled = FD_READ;
wilAwaitRead(TheSocket, hMainWnd);
}
else
{/* post the success message */
MsgEnabled = 0;
wilAwaitCancel(TheSocket, hMainWnd);
POST_MSG(AsyncSuccessMsg);
}
return TRUE;
case FD_WRITE:
/* socket is ready for writing */
if(MsgEnabled!=FD_WRITE) return TRUE;
/* ready to write */
if(EchoFlag)
{SERVER_PREFIX
DisplayLine(AsyncCmdPtr);
}
/* transmit command */
Code = wilWriteLine(TheSocket,AsyncCmdPtr);
if(Code<0)
{PostError(Code,"Write: ",AsyncFailureMsg);
return TRUE;
}
/* more to write ? */
if(Code<AsyncCmdLength)
{/* got more to send */
AsyncCmdPtr += (Code);
AsyncCmdLength -= (Code);
return TRUE;
}
/* write is completed */
if(AsyncExpectedRead)
{/* expect a response from server */
AsyncReadCount = 0;
MsgEnabled = FD_READ;
wilAwaitRead(TheSocket, hMainWnd);
}
else
{/* no response expected form server */
MsgEnabled = 0;
wilAwaitCancel(TheSocket, hMainWnd);
/* post the success message */
POST_MSG(AsyncSuccessMsg);
}
return TRUE;
case FD_READ:
/* socket has data */
if(MsgEnabled!=FD_READ) return TRUE;
/* incoming data ready to read */
switch(AsyncExpectedRead)
{
case ASYNC_MULTIPLE_LINES:
Code = wilReadLine(TheSocket,(LPSTR)InBuffer,MAX_BUF);
/* end of input ? */
if(Code==WIL_EOF)
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_MSG(AsyncSuccessMsg);
return TRUE;
}
/* error ? */
if(Code<0)
{PostError(Code,"Read1: ",AsyncFailureMsg);
return TRUE;
}
/* anything there ? */
if(Code>0)
{/* display buffer */
AsyncReadCount++;
if(EchoFlag)
{SERVER_PREFIX
DisplayString((LPSTR)InBuffer);
}
/* did we just get a '.' ? on a line by itself */
if( (*InBuffer=='.')
&&(*(InBuffer+1)=='\r')
&&(*(InBuffer+2)=='\n')
&&(Code==3) )
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_MSG(AsyncSuccessMsg);
}
return TRUE;
}
/* Code == 0 */
return TRUE;
case ASYNC_SINGLE_LINE:
/* expect single line from server */
AsyncReadCount++;
Code = wilReadLine(TheSocket,(LPSTR)InBuffer,MAX_BUF);
/* end of input ? */
if(Code==WIL_EOF)
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_MSG(AsyncSuccessMsg);
return TRUE;
}
/* error ? */
if(Code<0)
{PostError(Code,"Read2: ",AsyncFailureMsg);
return TRUE;
}
/* anything there ? */
if(Code>0)
{/* display buffer */
if(EchoFlag)
{SERVER_PREFIX
DisplayString((LPSTR)InBuffer);
}
}
/* Code >= 0 */
MsgEnabled = 0;
wilAwaitCancel(TheSocket, hMainWnd);
POST_MSG(AsyncSuccessMsg);
return TRUE;
case ASYNC_SINGLE_CODED:
AsyncReadCount++;
Code = wilWaitLine(TheSocket,(LPSTR)InBuffer,MAX_BUF, 0, 500);
/* end of input ? */
if(Code==WIL_EOF)
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_PARM(AsyncSuccessMsg,(long)-1);
return TRUE;
}
/* error ? */
if(Code<0)
{PostError(Code,"Read5: ",AsyncFailureMsg);
return TRUE;
}
/* anything there ? */
if(Code>0)
{/* display buffer */
if(EchoFlag)
{SERVER_PREFIX
DisplayString((LPSTR)InBuffer);
}
/* fetch response code */
AsyncResponse = (int) wilParseDecimal((LPSTR)InBuffer);
/* post response code */
wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_PARM(AsyncSuccessMsg,(long)AsyncResponse);
return TRUE;
}
/* Code == 0 */
return TRUE;
case ASYNC_MULTIPLE_CODED:
AsyncReadCount++;
Code = wilWaitLine(TheSocket,(LPSTR)InBuffer,MAX_BUF, 0, 500);
/* end of input ? */
if(Code==WIL_EOF)
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_PARM(AsyncSuccessMsg,(long)-1);
return TRUE;
}
/* error ? */
if(Code<0)
{PostError(Code,"Read3: ",AsyncFailureMsg);
return TRUE;
}
/* anything there ? */
if(Code>0)
{/* display buffer */
if(EchoFlag)
{SERVER_PREFIX
DisplayString((LPSTR)InBuffer);
}
/* fetch response code */
Code = (int) wilParseDecimal((LPSTR)InBuffer);
if(AsyncReadCount==1) AsyncResponse = Code;
/* post response code if this is last line of coded text */
if( (Code==AsyncResponse)
&&( (Code == 3) || (InBuffer[3]==' ') ) )
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_PARM(AsyncSuccessMsg,(long)AsyncResponse);
}
return TRUE;
}
/* Code == 0 */
return TRUE;
case ASYNC_PLUS_MINUS:
/* expect single line from server beginning with + or - */
AsyncReadCount++;
Code = wilReadLine(TheSocket,(LPSTR)InBuffer,MAX_BUF);
/* end of input ? */
if(Code==WIL_EOF)
{wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
POST_MSG(AsyncSuccessMsg);
return TRUE;
}
/* error ? */
if(Code<0)
{PostError(Code,"Read4: ",AsyncFailureMsg);
return TRUE;
}
/* anything there ? */
if(Code>0)
{/* display buffer */
if(EchoFlag)
{SERVER_PREFIX
DisplayString((LPSTR)InBuffer);
}
wilAwaitCancel(TheSocket, hMainWnd);
MsgEnabled = 0;
switch(*InBuffer)
{case '+':
POST_MSG(AsyncSuccessMsg);
return TRUE;
case '-':
POST_MSG(AsyncFailureMsg);
return TRUE;
default:
if(EchoFlag) DisplayLine("Expected +OK or -ERR");
POST_MSG(AsyncFailureMsg);
return TRUE;
}
}
/* Code == 0 */
return TRUE;
default:
MsgEnabled = 0;
return FALSE;
} /* end-switch(AsyncExpectedRead) */
default:
return FALSE;
} /* end-switch(LOWORD(lParam)) */
}
LPSTR AsyncGetBufPtr(void)
{
return (LPSTR) InBuffer;
}
int AsyncSetEcho(int Flag)
{int Last = EchoFlag;
EchoFlag = Flag;
return Last;
}
int AsyncSetDebug(int Flag)
{int Last = DebugFlag;
DebugFlag = Flag;
return Last;
}